/* 
 *	Copyright 2014  Yanqing Wu
 *		email: yqwu_yqwu@126.com
 *
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
*/

#include "stdafx.h"
#include "StdCtrlSkinRow.h"
#include "StdCtrlSkinTool_Utils.h"
#include "StdCtrlSkinTable.h"
#include "StdCtrlSkinBgCell.h"

void CStdCtrlSkinRow::InitDataElt(CStdCtrlSkinTable* pTable)
{
	weight = 0;
	cols = 0;
	m_pTable = pTable;
}

CStdCtrlSkinRow::CStdCtrlSkinRow(CStdCtrlSkinTable* pTable)
{
	InitDataElt(pTable);
}
CStdCtrlSkinRow::CStdCtrlSkinRow(CComPtr<IXMLDOMNode> spNode, CStdCtrlSkinTable* pTable)
{
	InitDataElt(pTable);
	LoadXmlNode(spNode);
	m_pTable = pTable;
}

CStdCtrlSkinRow::~CStdCtrlSkinRow(void)
{
	for(auto i : m_cell_list)
		delete i.second;
}

CString CStdCtrlSkinRow::GetFilePath(void)
{
	return m_pTable->GetFilePath();
}

bool CStdCtrlSkinRow::LoadXmlNode(CComPtr<IXMLDOMNode> spNode)
{
	auto attribPairs = StdCtrlSkinTool_XmlGetAttribPairs(spNode);
	CStdCtrlSkin_EnumAttrib attr;
	auto pEnum = StdCtrlSkinTool_GetEnum();
	//	Load attributes
	for(auto i:attribPairs)
	{
		auto name = i.first;
		auto value = i.second;
		auto correct = pEnum->Parse(attr, name);
		if ( !correct )
		{
			SetCustomAttrib(name, value);
			continue;
		}
		switch(attr)
		{
		case CStdCtrlSkin_EnumAttrib::WIDTH:
			attrib.width = StdCtrlSkinTool_CString2Long(value);
			break;
		case CStdCtrlSkin_EnumAttrib::HEIGHT:
			attrib.height = StdCtrlSkinTool_CString2Long(value);
			break;
		case CStdCtrlSkin_EnumAttrib::PADX:
			attrib.padx = StdCtrlSkinTool_CString2Long(value);
			break;
		case CStdCtrlSkin_EnumAttrib::PADY:
			attrib.pady = StdCtrlSkinTool_CString2Long(value);
			break;
		case CStdCtrlSkin_EnumAttrib::STICKY:
			pEnum->ParseCombo(attrib.sticky, value);
			break;
		case CStdCtrlSkin_EnumAttrib::WEIGHT:
			weight = StdCtrlSkinTool_CString2Long(value);
			break;
		default:
			SetCustomAttrib(name, value);
			break;
		}
	}
	//	Load sub nodes (cells)
	CComPtr<IXMLDOMNodeList> spChildren;
	spNode->get_childNodes(&spChildren);
	long length;
	spChildren->get_length(&length);
	CStdCtrlSkin_EnumSubNode type;
	CStdCtrlSkinCell* pLayoutCell, *pCell;
	CStdCtrlSkinBgCell* pBgCell;
	for(long i=0; i!=length; ++i)
	{
		CComPtr<IXMLDOMNode> spChild;
		spChildren->get_item(i, &spChild);
		auto name = StdCtrlSkinTool_XmlGetNodeName(spChild);
		pEnum->Parse(type, name);
		switch(type)
		{
		case CStdCtrlSkin_EnumSubNode::CELL:
			if ( m_pTable->IsLayoutTable() )
			{
				pLayoutCell = new CStdCtrlSkinCell(spChild, this);
				pCell = pLayoutCell;
			}
			else
			{
				pBgCell = new CStdCtrlSkinBgCell(spChild, this);
				pCell = (CStdCtrlSkinCell*)pBgCell;
			}
			m_cell_list[cols] = pCell;
			pCell->col = cols;
			cols ++;
			break;
		default:
			break;
		}
	}
	return true;
}

CStdCtrlSkinAttrib CStdCtrlSkinRow::GetAttribFinal(UINT col)
{
	auto resCol = m_pTable->GetColAttrib(col);
	auto result = StdCtrlSkinTool_MergeAttrib(attrib, resCol);
	return result;
}

std::map<LPARAM, UINT> CStdCtrlSkinRow::GetCellWidthStops(void)
{
	std::map<LPARAM, UINT> result;
	UINT width = 0;
	for(auto i:m_cell_list)
	{
		auto begin = i.first;
		auto pCell = i.second;
		width = pCell->GetMinWidth();
		auto end = begin + pCell->colspan;
		LPARAM key = MAKELPARAM(begin, end);
		result[key] = width;
	}
	return result;
}

std::map<LPARAM, UINT> CStdCtrlSkinRow::GetCellHeightStops(void)
{
	std::map<LPARAM, UINT> result;
	LPARAM key = MAKELPARAM(row, row+1);
	if ( attrib.height<0 )
		result[key] = 0;
	else
		result[key] = attrib.height;
	UINT height;
	for(auto i : m_cell_list)
	{
		auto pCell = i.second;
		auto span = pCell->rowspan;
		key = MAKELPARAM(row, row+span);
		height = pCell->GetMinHeight();
		if ( result.find(key) == result.end() )
			result[key] = height;
		else
			result[key] = max(result[key], height);
	}
	return result;
}

int CStdCtrlSkinRow::GetRowStart(int iRow)
{
	if ( iRow<0 )
		return m_pTable->GetRowStart(row);
	return m_pTable->GetRowStart(iRow);
}
int CStdCtrlSkinRow::GetRowEnd(int iRow)
{
	if ( iRow<0 )
		return m_pTable->GetRowEnd(row);
	return m_pTable->GetRowEnd(iRow);
}
int CStdCtrlSkinRow::GetColStart(UINT col)
{
	return m_pTable->GetColStart(col);
}
int CStdCtrlSkinRow::GetColEnd(UINT col)
{
	return m_pTable->GetColEnd(col);
}

void CStdCtrlSkinRow::GenerateName2Cell(std::map<CString, CStdCtrlSkinCell*>& name2cellList)
{
	for(auto i : m_cell_list)
	{
		auto pCell = i.second;
		auto name = pCell->ctrl_id;
		if ( name.Compare(_T("")) )
			name2cellList[name] = pCell;
	}
}

void CStdCtrlSkinRow::Draw(HDC hDC)
{
	for(auto i : m_cell_list)
	{
		CStdCtrlSkinBgCell* pCell = (CStdCtrlSkinBgCell*)i.second;
		pCell->Draw(hDC);
	}
}

#ifdef __DUMPTEST
void CStdCtrlSkinRow::Dump(std::ofstream& fio, CStdCtrlSkin_EnumDump type)
{
	for(auto i : m_cell_list)
		i.second->Dump(fio, type);
}
#endif